import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Not, In, Like } from 'typeorm';
import { Injectable } from '@nestjs/common';
import { ResultData } from 'src/common/utils/result';
import { CreateRecordsDto, UpdateRecordsDto, QueryRecordsDto } from './dto/records.dto';
import { RecordsEntity } from './entities/records.entity';
import { isEmpty } from 'src/common/utils';

@Injectable()
export class RecordsService {
  constructor(
    @InjectRepository(RecordsEntity)
    private readonly recordsEntityRep: Repository<RecordsEntity>,
  ) {}

  async create(createRecordsDto: CreateRecordsDto) {
    const res = await this.recordsEntityRep.save(createRecordsDto);
    return ResultData.ok(res);
  }

  async findAll(query: QueryRecordsDto) {
    const entity = this.recordsEntityRep.createQueryBuilder('entity');
    entity.where({ delFlag: '0' });
    if (!isEmpty(query.id)) {
      entity.andWhere('entity.id = :id', { id: query.id });
    }
    if (!isEmpty(query.sessionId)) {
      entity.andWhere('entity.sessionId = :sessionId', { sessionId: query.sessionId });
    }
    if (!isEmpty(query.content)) {
      entity.andWhere('entity.content = :content', { content: query.content });
    }
    if (!isEmpty(query.aiReply)) {
      entity.andWhere('entity.aiReply = :aiReply', { aiReply: query.aiReply });
    }
    if (!isEmpty(query.delFlag)) {
      entity.andWhere('entity.delFlag = :delFlag', { delFlag: query.delFlag });
    }
    if (!isEmpty(query.createTime)) {
      entity.andWhere('entity.createTime BETWEEN :start AND :end', { start: query.createTime[0], end: query.createTime[1] });
    }
    if (!isEmpty(query.updateTime)) {
      entity.andWhere('entity.updateTime BETWEEN :start AND :end', { start: query.updateTime[0], end: query.updateTime[1] });
    }
    entity.select(['entity.id', 'entity.sessionId', 'entity.content', 'entity.aiReply', 'entity.delFlag', 'entity.createTime', 'entity.updateTime']);

    if (query.orderByColumn && query.isAsc) {
      const key = query.isAsc === 'ascending' ? 'ASC' : 'DESC';
      entity.orderBy(`entity.${query.orderByColumn}`, key);
    }

    if (query.pageNum && query.pageSize) {
      entity.skip(query.pageSize * (query.pageNum - 1)).take(query.pageSize);
    }

    const [list, total] = await entity.getManyAndCount();

    return ResultData.ok({
      list,
      total,
    });
  }

  async findOne(id: number) {
    const res = await this.recordsEntityRep.findOne({
      where: {
        delFlag: '0',
        id: id,
      },
    });
    return ResultData.ok(res);
  }

  async update(updateRecordsDto: UpdateRecordsDto) {
    const res = await this.recordsEntityRep.update({ id: updateRecordsDto.id }, updateRecordsDto);
    return ResultData.ok({ value: res.affected >= 1 });
  }

  async remove(ids: number[]) {
    const res = await this.recordsEntityRep.update(
      { id: In(ids) },
      {
        delFlag: '1',
      },
    );
    return ResultData.ok({ value: res.affected >= 1 });
  }

  // 使用原生SQL进行多表联查
  async get(userId: number, start: string, end: string) {
    const sql = `
        SELECT cr.id, cr.content, cr.ai_reply as aiReply
        FROM conversation_records cr
                 INNER JOIN session s ON cr.session_id = s.id
        WHERE s.user_id = ?
          AND s.create_time BETWEEN ?  AND ? 
          AND s.del_flag = '0'
          AND cr.del_flag = '0'
        ORDER BY s.id DESC;
    `;

    // 执行原生SQL查询
    return await this.recordsEntityRep.query(sql, [userId, start, end]);
  }

  async findSessionContext(sessionId: number) {
    const sql = `
        SELECT cr.id, cr.content, cr.ai_reply as aiReply
        FROM conversation_records cr
                 INNER JOIN session s ON cr.session_id = s.id
        WHERE s.id = ?
          AND s.del_flag = '0'
          AND cr.del_flag = '0'
        ORDER BY cr.id ASC;
    `;

    // 执行原生SQL查询
    const rawRecords = await this.recordsEntityRep.query(sql, [sessionId]);

    // 转换格式：每个原始记录拆分为用户和助手两条消息
    const formattedContext: Array<{ role: 'user' | 'assistant' | 'system'; content: string }> = [];
    formattedContext.push({
      role: 'system',
      content:
        '## 核心定位\n' +
        '你是一个名为“谛芯老师”的家庭亲子陪伴支持顾问，以“家庭亲子陪伴支持顾问”身份，专注青少年心理状态理解与家长协同支持，定位为陪伴者与协作者，协助家长发现孩子行为背后的需求，共同推进切实可行的微小行动。\n' +
        '\n' +
        '## 首轮回应规范\n' +
        '1. 优先共情家长的情绪状态，用平实语言接纳其感受，不添加额外评价。\n' +
        '2. 交流过程循序渐进，回答时需要有反问机制，紧跟1-2开放式问题，聚焦可观察的具体细节，例如：孩子该行为出现多久了？在哪些场景下（如学习时、与人相处时）更易出现？近期孩子的生活中是否有明显变化（如换环境、作息调整）？孩子出现该情况时，会有哪些具体的言语或行为表现？\n' +
        '3. 首轮绝对禁止分析原因、归类问题、贴标签或提供任何解决方案。\n' +
        '\n' +
        '## 语言表达要求\n' +
        '1. 采用客观、清晰的书面语，禁用口语化词汇，例如：其实、咱们、挺、咋、呗、啊、呢等。\n' +
        '2. 杜绝一切心理学专业术语，例如：干预、情绪调节、注意力缺陷、心理压力源、认知偏差等。\n' +
        '3. 用具体行为描述替代抽象概念，例如：“陪孩子安静坐5分钟，听他说说当下的感受”而非“提供情绪支持”，“和孩子一起梳理当天的小事”而非“促进认知整合”。\n' +
        '\n' +
        '## 内容边界准则\n' +
        '1. 不评判儿童行为与家长教养方式，禁用标签化语言，例如：不听话、叛逆、不懂事、管教不当、溺爱、失职等。\n' +
        '2. 表述需聚焦事实与中性描述，例如：“孩子近期可能处于情绪波动期”“当前与孩子的互动节奏可慢慢调整”“孩子该行为出现的频率有所增加”。\n' +
        '\n' +
        '## 建议提供规范\n' +
        '1. 仅在家长补充足够背景信息（含行为情境、频率、相关细节及家长已尝试的做法）后，方可提供建议。\n' +
        '2. 建议需满足“可操作”核心：任务微小、耗时短（单次不超过15分钟）、无需额外准备，单次仅提供1-2项。\n' +
        '3. 建议采用分级呈现，例如：“第一步可尝试……”“接下来若情况允许，可试试……”。\n' +
        '4. 每条建议后需补充宽松导向的提示，例如：“无需追求完美效果，偶尔没做到也没关系”“以孩子不抵触为前提，过程中可灵活调整”。\n' +
        '\n' +
        '## 互动沟通原则\n' +
        '1. 坚持“协同探索”立场，使用合作式措辞，例如：我们可以一起试试……您是否愿意尝试……咱们可以观察看看……\n' +
        '2. 主动肯定家长的具体行动与觉察，例如：“您留意到孩子的细微变化并主动寻求支持，这对孩子来说很重要”“您之前尝试的XX做法，已经体现了对孩子的用心”，强化家长的信心与主体性。\n' +
        '3. 禁用指令性语言，例如：必须、一定要、赶紧、马上、不许等。\n' +
        '\n' +
        '## 绝对禁止事项\n' +
        '1. 禁止出现括号内的注释、动作描写、表情提示、语气说明或场景脑补，例如：（温和地说）、（注视着你）、（无奈地摇头）等。\n' +
        '2. 禁止一次性输出多维度分析、长段落解释、复合型方案或复杂理论。\n' +
        '3. 禁止承诺具体效果，例如：“这样做一定能改善”“尝试后孩子就会改变”等表述。',
    });

    for (const record of rawRecords) {
      // 添加用户消息（role为user，内容为content）
      formattedContext.push({
        role: 'user',
        content: record.content,
      });

      // 添加助手消息（role为assistant，内容为aiReply）
      formattedContext.push({
        role: 'assistant',
        content: record.aiReply,
      });
    }

    return formattedContext;
  }
}
